﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Media;

using Uhi.Libraries.Windows.Interactivity;

using Uhi.Applications.FileAid.View;

namespace Uhi.Applications.FileAid.Interactivity
{
    #region SelectTextAction
    /// <summary>
    /// <see cref="ListBox"/> 内の指定範囲のテキストを選択する <see cref="TriggerAction{T}"/>。
    /// </summary>
    public class SelectTextAction : TriggerAction<ListBox>
    {
        #region Invoke
        /// <summary>
        /// <see cref="ListBox"/> 内の指定範囲のテキストを選択する。
        /// </summary>
        /// <param name="parameter">アクションへのパラメータ。</param>
        protected override void Invoke(object parameter)
        {
            var args = parameter as InteractionRequestEventArgs;
            var selection = args.EventData as TextSelection;

            var listbox = this.AssociatedObject;
            var container = listbox.ItemContainerGenerator.ContainerFromIndex(selection.SelectionRow);

            if (container == null)
            {
                listbox.SelectedIndex = selection.SelectionRow;
                listbox.ScrollIntoView(listbox.SelectedItem);
                listbox.UpdateLayout();
                container = listbox.ItemContainerGenerator.ContainerFromIndex(selection.SelectionRow);
            }

            var presenter = this.FindVisualChild<ContentPresenter>(container);
            var template = presenter.ContentTemplate;
            var textBox = template.FindName("StrText", presenter) as TextEditor;

            textBox.Focus();
            textBox.CaretIndex = selection.SelectionStart;
        }
        #endregion

        #region FindVisualChild
        /// <summary>
        /// 指定した <see cref="DependencyObject"/> の任意の型の子要素を取得する。
        /// </summary>
        /// <typeparam name="T">検索対象の型。</typeparam>
        /// <param name="obj">検索対象の親要素。</param>
        /// <returns>任意の型の子要素。</returns>
        private T FindVisualChild<T>(DependencyObject obj)
            where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                var child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is T)
                    return child as T;
                else
                {
                    var childOfChild = this.FindVisualChild<T>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
        }
        #endregion
    }
    #endregion
}
